﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.MountAndBlade.View.ViewCreatorManager
// Assembly: TaleWorlds.MountAndBlade.View, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 61152EB8-513B-4D4A-8AC0-0D1465C6CF6C
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\Modules\Native\bin\Win64_Shipping_Client\TaleWorlds.MountAndBlade.View.dll

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using TaleWorlds.Library;
using TaleWorlds.MountAndBlade.View.MissionViews;
using TaleWorlds.ScreenSystem;

#nullable disable
namespace TaleWorlds.MountAndBlade.View
{
  public static class ViewCreatorManager
  {
    private static Dictionary<string, MethodInfo> _viewCreators = new Dictionary<string, MethodInfo>();
    private static Dictionary<System.Type, System.Type> _actualViewTypes = new Dictionary<System.Type, System.Type>();
    private static Dictionary<System.Type, System.Type> _defaultTypes = new Dictionary<System.Type, System.Type>();

    static ViewCreatorManager()
    {
      Assembly[] viewAssemblies = ViewCreatorManager.GetViewAssemblies();
      Assembly assembly1 = typeof (ViewCreatorModule).Assembly;
      ViewCreatorManager.CheckAssemblyScreens(assembly1);
      foreach (Assembly assembly2 in viewAssemblies)
        ViewCreatorManager.CheckAssemblyScreens(assembly2);
      ViewCreatorManager.CollectDefaults(assembly1);
      foreach (Assembly assembly3 in viewAssemblies)
        ViewCreatorManager.CollectDefaults(assembly3);
      foreach (Assembly assembly4 in viewAssemblies)
        ViewCreatorManager.CheckOverridenViews(assembly4);
    }

    private static void CheckAssemblyScreens(Assembly assembly)
    {
      foreach (System.Type type in assembly.GetTypesSafe())
      {
        object[] customAttributesSafe = type.GetCustomAttributesSafe(typeof (ViewCreatorModule), false);
        if (customAttributesSafe != null && customAttributesSafe.Length == 1 && customAttributesSafe[0] is ViewCreatorModule)
        {
          foreach (MethodInfo method in type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
          {
            if (method.GetCustomAttributesSafe(typeof (ViewMethod), false)[0] is ViewMethod viewMethod)
              ViewCreatorManager._viewCreators.Add(viewMethod.Name, method);
          }
        }
      }
    }

    private static Assembly[] GetViewAssemblies()
    {
      List<Assembly> assemblyList = new List<Assembly>();
      Assembly assembly1 = typeof (ViewCreatorModule).Assembly;
      foreach (Assembly assembly2 in AppDomain.CurrentDomain.GetAssemblies())
      {
        foreach (object referencedAssembly in assembly2.GetReferencedAssemblies())
        {
          if (referencedAssembly.ToString() == assembly1.GetName().ToString())
          {
            assemblyList.Add(assembly2);
            break;
          }
        }
      }
      return assemblyList.ToArray();
    }

    internal static IEnumerable<MissionBehavior> CreateDefaultMissionBehaviors(Mission mission)
    {
      List<MissionBehavior> missionBehaviors = new List<MissionBehavior>();
      foreach (KeyValuePair<System.Type, System.Type> defaultType in ViewCreatorManager._defaultTypes)
      {
        if (!defaultType.Value.IsAbstract)
        {
          MissionBehavior instance = Activator.CreateInstance(defaultType.Value) as MissionBehavior;
          missionBehaviors.Add(instance);
        }
      }
      return (IEnumerable<MissionBehavior>) missionBehaviors;
    }

    internal static IEnumerable<MissionBehavior> CollectMissionBehaviors(
      string missionName,
      Mission mission,
      IEnumerable<MissionBehavior> behaviors)
    {
      List<MissionBehavior> second = new List<MissionBehavior>();
      if (ViewCreatorManager._viewCreators.ContainsKey(missionName))
      {
        MissionBehavior[] collection = ViewCreatorManager._viewCreators[missionName].Invoke((object) null, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, (Binder) null, new object[1]
        {
          (object) mission
        }, (CultureInfo) null) as MissionBehavior[];
        second.AddRange((IEnumerable<MissionBehavior>) collection);
      }
      return behaviors.Concat<MissionBehavior>((IEnumerable<MissionBehavior>) second);
    }

    public static ScreenBase CreateScreenView<T>() where T : ScreenBase, new()
    {
      return ViewCreatorManager._actualViewTypes.ContainsKey(typeof (T)) ? Activator.CreateInstance(ViewCreatorManager._actualViewTypes[typeof (T)]) as ScreenBase : (ScreenBase) new T();
    }

    public static ScreenBase CreateScreenView<T>(params object[] parameters) where T : ScreenBase
    {
      System.Type type = typeof (T);
      if (ViewCreatorManager._actualViewTypes.ContainsKey(typeof (T)))
        type = ViewCreatorManager._actualViewTypes[typeof (T)];
      return Activator.CreateInstance(type, parameters) as ScreenBase;
    }

    public static MissionView CreateMissionView<T>(
      bool isNetwork = false,
      Mission mission = null,
      params object[] parameters)
      where T : MissionView, new()
    {
      int num = isNetwork ? 1 : 0;
      return ViewCreatorManager._actualViewTypes.ContainsKey(typeof (T)) ? Activator.CreateInstance(ViewCreatorManager._actualViewTypes[typeof (T)], parameters) as MissionView : (MissionView) new T();
    }

    public static MissionView CreateMissionViewWithArgs<T>(params object[] parameters) where T : MissionView
    {
      System.Type type = typeof (T);
      if (ViewCreatorManager._actualViewTypes.ContainsKey(typeof (T)))
        type = ViewCreatorManager._actualViewTypes[typeof (T)];
      return Activator.CreateInstance(type, parameters) as MissionView;
    }

    private static void CheckOverridenViews(Assembly assembly)
    {
      foreach (System.Type type in assembly.GetTypesSafe())
      {
        if (typeof (MissionView).IsAssignableFrom(type) || typeof (ScreenBase).IsAssignableFrom(type))
        {
          object[] customAttributesSafe = type.GetCustomAttributesSafe(typeof (OverrideView), false);
          if (customAttributesSafe != null && customAttributesSafe.Length == 1 && customAttributesSafe[0] is OverrideView overrideView)
          {
            ViewCreatorManager._actualViewTypes[overrideView.BaseType] = type;
            if (ViewCreatorManager._defaultTypes.ContainsKey(overrideView.BaseType))
              ViewCreatorManager._defaultTypes[overrideView.BaseType] = type;
          }
        }
      }
    }

    private static void CollectDefaults(Assembly assembly)
    {
      foreach (System.Type type in assembly.GetTypesSafe())
      {
        if (typeof (MissionBehavior).IsAssignableFrom(type) && type.GetCustomAttributesSafe(typeof (DefaultView), false).Length == 1)
          ViewCreatorManager._defaultTypes.Add(type, type);
      }
    }
  }
}
